package Common

import(
    "bytes"
    "encoding/binary"
    "fmt"
    "net"
    "io"
    "time"
    "encoding/json"
)

type SearchParam struct {
    Word      string  `json:"word"`
    Cnt       int     `json:"cnt"`
    Page      int     `json:"page"`
    Detail    int     `json:"detail"`
}


// Encode 将消息编码
func Encode(message string) ([]byte, error) {
    var length = int32(len(message))
    var pkg = new(bytes.Buffer)
    fmt.Println("head len:", length)
    //通过小端序列的方式把length写到pkg
    err := binary.Write(pkg, binary.LittleEndian, length)
    if err != nil {
        return nil, err
    }
    //在通过小端序列的方式把真实的包内容写入bytes，封装成一个包。
    err = binary.Write(pkg, binary.LittleEndian, []byte(message))
    if err != nil {
        return nil, err
    }
    return pkg.Bytes(), nil
}

/*
// Decode 解码消息
func Decode(reader *bufio.Reader) (string, error) {
    // 读取前4个字节的数据，及包的内容长度，endoce 里面的length。Peek的方式读取内容，是不会清掉缓存的
    lengthByte, _ := reader.Peek(4)
    lengthBuff := bytes.NewBuffer(lengthByte) //定义一个以lengthByte为内容的bytes缓冲区
    var length int32
    err := binary.Read(lengthBuff, binary.LittleEndian, &length)// 将lengthBuff 的内容写到length里面。这里要相应解码才能读取到length的内容
    if err != nil {
        return "", err
    }
    // Buffered返回缓冲中现有的可读取的字节数。前面用Peek读取，所以这里数据内容应该大于length+4
    if int32(reader.Buffered()) < length+4 {
        return "", err
    }

    // 读取真正的消息数据
    pack := make([]byte, int(4+length))
    _, err = reader.Read(pack) 
    if err != nil {
        return "", err
    }
    return string(pack[4:]), nil
}
*/
func Search(word string, cnt int, page int, detail int) (bool, string){
    conn, err := net.Dial("tcp", "127.0.0.1:8090")
    defer conn.Close()
    if err != nil {
        fmt.Println("conn err:",err)
        return false,""
    }

    var searchParam SearchParam
    searchParam.Word = word
    searchParam.Cnt  = cnt 
    searchParam.Page = page
    searchParam.Detail = detail

    search_str, _ := json.Marshal(searchParam)
    search_json_str := string(search_str)

    query_param, err := Encode(search_json_str)
    if err != nil {
        fmt.Println("Encode err:", err)
        return false,""
    }
    send_cnt, err := conn.Write(query_param)
    if err != nil {
        fmt.Println("write err:", err)
        return false,""
    }
    fmt.Println("send_cnt:", send_cnt)
    //读取包头
    head := make([]byte, 4)
    _ = conn.SetReadDeadline(time.Now().Add(time.Second * 3))
    _, err = io.ReadFull(conn, head)
    if nil != err {
        fmt.Println("read head fail.")
        return false,""
    }
    bodyLen := binary.LittleEndian.Uint32(head) 

    //读取包体
    bodyData := make([]byte, bodyLen)
    _ = conn.SetReadDeadline(time.Now().Add(time.Second * 3))
    _, err = io.ReadFull(conn, bodyData)
    if nil != err {
        fmt.Println("read body fail.")
        return false,""
    }
    fmt.Println("search success:")
    return true,string(bodyData)
}
